package br.com.vexillum.view;

import java.lang.reflect.Method;
import java.util.List;

import org.springframework.util.StringUtils;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Session;
import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zkplus.databind.AnnotateDataBinder;

import br.com.vexillum.control.manager.ConfigurationManager;
import br.com.vexillum.control.manager.ExceptionManager;
import br.com.vexillum.model.UserBasic;
import br.com.vexillum.util.Message;
import br.com.vexillum.util.Return;

@SuppressWarnings("rawtypes")
public class GenericComposer extends
		GenericForwardComposer {

	private static final long serialVersionUID = 1L;

	protected AnnotateDataBinder binder;
	
	protected Component component;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.zkoss.zk.ui.util.GenericForwardComposer#doAfterCompose(org.zkoss.
	 * zk.ui.Component) M�todo dever� ser sobrescrito para cada composer
	 */
	@SuppressWarnings("unchecked")
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		comp.setAttribute("controller", this);
		this.component = comp;
		initBinder(component);
	}

	protected AnnotateDataBinder initBinder(Component comp) {
		binder = new AnnotateDataBinder(comp);
		binder.setLoadOnSave(false);
		//binder.loadAll();
		return binder;
	}
	
	protected void loadBinder(){
		binder.loadAll();
	}

	public boolean doAction(String action) {
		Return ret = null;
		
//		binder.saveAll();
		Class<?> rclass = this.getClass();
		try {
			Method m = rclass.getMethod(action, new Class[]{});
			ret =  (Return) m.invoke(this, new Object[]{});
		} catch (Exception e) {
			ret =  new ExceptionManager(e).treatException();
		} 
		loadBinder();
		treatReturn(ret);
		return ret.isValid();
	}	

	public void treatReturn(Return ret){
		if(ret != null && ret.getMessages() != null && !ret.getMessages().isEmpty() ){
			String type = ret.isValid() ? "info":"error";
			showNotifications(ret.getMessages(), type);
		}		
	}
	
	/**
	 * M�todo que procurar um Component do ZK baseado no ID do mesmo
	 * @param comp Componente pai, onde ser� procuradom o componente com o ID correspondente
	 * @param id ID do componente a ser procurado
	 * @return Retorna o componente com o ID procurado, ou retorna null caso n�o seja encontrado
	 */
	public Component getComponentById(Component comp, String id){
		if(comp.getId().equals(id)){
			return comp;
		}		
		List<Component> allComps = comp.getChildren();
		for(Component c : allComps){			
			Component aux = getComponentById(c, id);
			if(aux != null){
				return aux;
			}
		}
		return null;
	}
	
	public static String getProperty(String key){
		return ConfigurationManager.getManager().getProperty(key, getUserInSession());
	}
	
	public static boolean isLogged(){
		Session s = Sessions.getCurrent(false);
		if(s == null || s.getAttribute("logged") == null || !s.getAttribute("logged").equals("true")){
			//TODO Mudar para false quando o login for implementado
			return true;
		}
		return true;
	}
	
	public void showNotifications(List<Message> messages, String type){
		String geralMessage = "";
		for (Message message : messages) {
			if(message.getAssociated() == null || message.getAssociated().equals("")){
				geralMessage += message.getMessage() + "<br><br>";
			} else {
				Clients.showNotification(message.getMessage(), type, getComponentById(component, "fld" + StringUtils.capitalize(message.getAssociated())), "end_center", 0, true);
			}
		}
		if(!geralMessage.equals("")){
			Clients.showNotification(geralMessage, type, null, "middle_center", 0, true);
		}
	}
	
	public void showBusyServer(Component comp, String message){
		String aux = message + "...";
		if(comp != null)
			Clients.showBusy(comp, aux);
		else Clients.showBusy(aux);
	}
	
	public static UserBasic getUserInSession(){
		UserBasic user = new UserBasic();
		user.setId((long) 1);
		return user;
	}
	
}
